import re
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthQQUser
from users.models import User
from . utils import OAuthQQ

class OAuthLoginSerializer(serializers.ModelSerializer):
    """QQ登录绑定序列化器"""
    access_token = serializers.CharField(label="qq绑定openid生成的token", write_only=True)
    token = serializers.CharField(label="jwt用户登录签发token", read_only=True)
    sms_code = serializers.CharField(label="手机验证码", write_only=True)

    class Meta:
        model = User
        fields = ("id", "username", "mobile", "password", "sms_code", "access_token", "token")
        read_only_fields = ("username",)
        exact_kwargs = {
            "password": {
                "write_only": True,
                "min_length": 8,
                "max_length": 20,
                "error_messages": {
                    "min_length": "密码不能少于5位",
                    "max_length": "密码不能超过20位"
                }
            }
        }

    def validate_mobile(self, value):
        if re.match(r"^1[3-9][0-9]{9}$", value):
            return value
        else:
            raise serializers.ValidationError("手机号格式不正确")

    def validate(self, attrs):
        mobile = attrs["mobile"]
        sms_code = attrs["sms_code"]
        access_token = attrs["access_token"]
        password = attrs["password"]
        redis_conn = get_redis_connection("verify_codes")
        real_sms_code = redis_conn.get("sms_code_%s" % mobile)
        if not real_sms_code:
            raise serializers.ValidationError("手机验证码无效")

        redis_conn.delete("sms_code_%s" % mobile) # 到底要不要删除手机号验证码
        if real_sms_code.decode().lower() != sms_code:
            raise serializers.ValidationError("手机验证码错误")

        # 校验access_token
        openid = OAuthQQ.check_qq_user_token(access_token)
        if not openid:
            raise serializers.ValidationError("绑定身份校验失败")
        attrs["openid"] = openid

        # 校验此手机是否注册过
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            pass
        else:
            if user.check_password(password):
                attrs["user"] = user
            else:
                raise serializers.ValidationError("密码输入错误")
        return attrs


    def create(self, validated_data):
        mobile = validated_data["mobile"]
        password = validated_data["password"]
        openid = validated_data["openid"]
        user = validated_data.get("user")

        if not user:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        oauthqquser = OAuthQQUser.objects.create(openid=openid, user=user)
        oauthqquser.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        user.save()
        return user
